﻿using Nasty.Core.Session;
using Nasty.Core.Entity;
using Nasty.Core.SuperExtension;
using SqlSugar;
using Newtonsoft.Json;
using Nasty.Core.Attributes;

namespace Nasty.Core.Entity.System
{
    [SugarTable("SysDepartment", TableDescription = "部门")]
    public class Department : StandardEntity<Department>
    {
        /// <summary>
        /// 名称
        /// </summary>
        [NastyColumn(ColumnName = "Name", ColumnDescription = "名称", Required = true)]
        public string? Name { get; set; }

        /// <summary>
        /// 编码
        /// </summary>
        [NastyColumn(ColumnName = "Code", ColumnDescription = "编码", Required = true, IsRepeat = true)]
        public string? Code { get; set; }

        /// <summary>
        /// 父级部门Id
        /// </summary>
        [NastyColumn(ColumnName = "ParentId", IsNullable = true, ColumnDescription = "父级部门Id")]
        public string? ParentId { get; set; }

        /// <summary>
        /// 部门角色Id
        /// </summary>
        [NastyColumn(ColumnName = "RoleId", IsNullable = true, ColumnDescription = "部门角色Id")]
        public string? RoleId { get; set; }

        /// <summary>
        /// 是否末级部门
        /// </summary>
        [NastyColumn(ColumnName = "IsLeaf", ColumnDescription = "是否末级部门")]
        public bool? IsLeaf { get; set; }

        /// <summary>
        /// 流水号 - 用于唯一标识部门 也记录记录了上级父级 流水号信息 
        /// 四位为一个单位 例如 0001-0002-0003-0004
        /// 流水号是可以变更的，部门移动或者上级部门移动时，流水号也会变更
        /// 不建议使用流水号作为固定标记码查询
        /// 该字段主要用于父级部门方便批量查询本部门以及子部门所有成员
        /// </summary>
        [NastyColumn(ColumnName = "SerialNumber", ColumnDescription = "流水号")]
        public string? SerialNumber { get; set; }

        /// <summary>
        /// 部门角色
        /// </summary>
        [Navigate(NavigateType.OneToOne, nameof(Department.RoleId), nameof(Department.Role.Id))]
        public Role? Role { get; set; }

        /// <summary>
        /// 部门用户
        /// </summary>
        [Navigate(typeof(DepartmentUser), nameof(DepartmentUser.DepartmentId), nameof(DepartmentUser.UserId))]
        public List<User>? Users { get; set; }


        public override void OnPreAdd()
        {
            base.OnPreAdd();
            var db = AppSession.CurrentDb.Value;

            try
            {
                //{
                //    var isAny = db.Queryable<Department>().Where((t) => t.Code == this.Code).Any();
                //    if (isAny) throw new Exception("编码重复");
                //}

                {
                    var role = new Role()
                    {
                        Type = RoleType.Department,
                        Name = Name,
                        Code = $"Dept-{Code}",
                    };

                    db.Save<Role>(role);

                    this.RoleId = role.Id;
                }

                {

                    if (!string.IsNullOrEmpty(this.ParentId))
                    {
                        db.Updateable<Department>()
                         .SetColumns((t) => new Department() { IsLeaf = false })
                         .Where((t) => t.Id == this.ParentId)
                         .ExecuteCommand();
                    }
                }


                this.IsLeaf = true;

                this.SerialNumber = GenerateSerialNumber(this.ParentId);
            }
            catch (Exception ex)
            {
                throw new Exception("创建部门角色失败", ex);
            }
        }


        public override void OnPreDelete()
        {
            base.OnPreDelete();

            var db = AppSession.CurrentDb.Value;
            db.Deleteable<Role>().Where((t) => t.Id == this.RoleId).ExecuteCommand();

            {
                db.Deleteable<DepartmentUser>().Where((t) => t.DepartmentId == this.Id).ExecuteCommand();
            }

            {
                if (!string.IsNullOrEmpty(this.ParentId))
                {
                    //父级部门是否存在其他子级部门并且子级部门不等于当前部门
                    var isAny = db.Queryable<Department>().Where((t) => t.ParentId == t.ParentId && t.Id != t.Id).Any();
                    if (!isAny)
                    {
                        db.Updateable<Department>()
                             .SetColumns((t) => new Department() { IsLeaf = true })
                             .Where((t) => t.Id == this.ParentId)
                             .ExecuteCommand();
                    }
                }
            }
        }


        public static string GenerateSerialNumber(string? parentId)
        {
            var db = AppSession.CurrentDb.Value;
            if (string.IsNullOrEmpty(parentId))
            {
                var last = db.Queryable<Department>().Where((t) => string.IsNullOrEmpty(t.ParentId)).OrderBy((t) => t.CreateTime, OrderByType.Desc).First();
                if (last == null) return "0001";

                var sn = int.Parse(last.SerialNumber) + 1;
                return sn.ToString().PadLeft(4, '0');
            }
            else
            {
                var parent = db.Queryable<Department>().Where((t) => t.Id == parentId).First();
                if (parent == null) throw new Exception("父级部门异常");

                var last = db.Queryable<Department>().Where((t) => t.ParentId == parentId).OrderBy((t) => t.CreateTime, OrderByType.Desc).First();
                if (last == null)
                {
                    if (parent == null) throw new Exception("父级部门异常");
                    return $"{parent.SerialNumber}-0001";
                }
                else
                {
                    var sn = int.Parse(last.SerialNumber.Split('-').Last()) + 1;
                    return $"{parent.SerialNumber}-{sn.ToString().PadLeft(4, '0')}";
                }
            }

        }
    }
}
